package com.cheng.im.service.group.service.impl;

import com.cheng.im.common.bean.msg.ProtoMsgV1;
import com.cheng.im.common.cocurrent.FutureTaskScheduler;
import com.cheng.im.common.constants.SeqConstants;
import com.cheng.im.common.entity.SessionCache;
import com.cheng.im.common.protobuiler.MessageAckBuild;
import com.cheng.im.service.common.resp.CommonResult;
import com.cheng.im.service.group.service.ImGroupMemberService;
import com.cheng.im.service.massage.service.impl.MessageStoreService;
import com.cheng.im.service.message.service.CheckSendMessageService;
import com.cheng.im.service.mq.RocketMQProduce;
import com.cheng.im.service.protobuilder.MessageGroupBuilder;
import com.cheng.im.service.protobuilder.P2PMessageBuilder;
import com.cheng.im.service.redis.seq.RedisSeq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class GroupMessageService {

    @Resource
    MessageStoreService messageStoreService;
    @Resource
    RocketMQProduce rocketMQProduce;
    @Resource
    RedisSeq redisSeq;
    @Resource
    MessageGroupBuilder messageGroupBuilder;
    @Resource
    ImGroupMemberService imGroupMemberService;
    @Resource
    CheckSendMessageService checkSendMessageService;

    public void process(ProtoMsgV1.Message message){
        //前置校验
        //这个用户是否被禁言 是否被禁用
        //发送方和接收方是否是好友

        // 去重
        ProtoMsgV1.Message messageFromMessageIdCache = messageStoreService
                .getMessageFromMessageIdCache(message.getAppId(),
                        message.getMessageGroupRequest().getMsgSdkUuid(),
                        ProtoMsgV1.Message.class);
        if(messageFromMessageIdCache != null){
            FutureTaskScheduler.add(() ->{
                //1.回ack成功给自己
                ack(messageFromMessageIdCache);
                //2.发消息给同步在线端
                syncToSender(messageFromMessageIdCache);
                //3.发消息给对方在线端
                dispatchMessage(messageFromMessageIdCache);
            });
        }

        long seq = redisSeq.doGetSeq(message.getAppId() + ":" + SeqConstants.GROUP_MESSAGE
                + message.getMessageGroupRequest().getGroupId());

        ProtoMsgV1.Message pkg = messageGroupBuilder.updateSeqAndMsgId(message, seq);
        FutureTaskScheduler.add(() ->{
            messageStoreService.storeGroupMessage(pkg);

            List<String> groupMemberId = imGroupMemberService.getGroupMemberId(pkg.getMessageGroupRequest().getGroupId(),
                    pkg.getAppId());

            // todo: 离线缓存
//            OfflineMessageContent offlineMessageContent = new OfflineMessageContent();
//            BeanUtils.copyProperties(messageContent,offlineMessageContent);
//            offlineMessageContent.setToId(messageContent.getGroupId());
//            messageStoreService.storeGroupOfflineMessage(offlineMessageContent,groupMemberId);

            //1.回ack成功给自己
            ack(pkg);
            //2.发消息给同步在线端
            syncToSender(pkg);
            //3.发消息给对方在线端
            dispatchMessage(pkg, groupMemberId);

            messageStoreService.setMessageFromMessageIdCache(pkg.getAppId(),
                    pkg.getMessageGroupRequest().getMsgSdkUuid(), pkg);
        });
    }

    private void ack(ProtoMsgV1.Message pkg){

        ProtoMsgV1.Message message = MessageAckBuild.messageAckBuild(pkg, pkg.getMessageGroupRequest().getFrom(),
                pkg.getMessageRequest().getFrom(), pkg.getMessageGroupRequest().getMsgSdkUuid(),
                pkg.getMessageGroupRequest().getMsgId());
        log.info("群聊ack消息为：{}", message);
        rocketMQProduce.sendToUser(message.getMessageAck().getFrom(), pkg);
    }

    private void syncToSender(ProtoMsgV1.Message pkg){
        rocketMQProduce.sendToUserExceptClient(pkg.getMessageGroupRequest().getFrom(), pkg);
    }

    private void dispatchMessage(ProtoMsgV1.Message pkg){
        List<String> groupMemberId = imGroupMemberService
                .getGroupMemberId(pkg.getMessageGroupRequest().getGroupId(), pkg.getAppId());
        for (String userId : groupMemberId) {
            if (!userId.equals(pkg.getMessageGroupRequest().getFrom())) {
                rocketMQProduce.dispatchMessage(userId, pkg);
            }
        }
    }

    private void dispatchMessage(ProtoMsgV1.Message pkg, List<String> groupMemberId){
        for (String userId : groupMemberId) {
            if (!userId.equals(pkg.getMessageGroupRequest().getFrom())) {
                rocketMQProduce.dispatchMessage(userId, pkg);
            }
        }
    }

    private CommonResult imServerPermissionCheck(String fromId, String toId, String appId){
        CommonResult responseVO = checkSendMessageService
                .checkGroupMessage(fromId, toId, appId);
        return responseVO;
    }
}
